package model.map;

import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

import model.area_effect.MapAreaOfEffect;
import model.area_effect.SkillObject;
import model.area_effect.Trap;
import model.entity.Entity;
import model.item.InventoryItem;


/**
 * State representing a tile that the Avatar can 
 * currently see.
 * @author Zachary
 */
public class CurrentlyViewable extends MapTileState {
	/**
	 * Constructor for this state.
	 * @param map
	 * @param point
	 */
	public CurrentlyViewable(GameMap map, MapPoint point) {
		super(map, point);
	}

	/**
	 * Changes the state of the tile to shrouded.
	 */
	public void updateState() {
		int distance = MapPoint.findDistance(point, this.getAvatar().getLocation());
		int range = this.getAvatar().getViewRange();
		
		if(distance > range)
			return;
		
		Shrouded shrouded = new Shrouded(this.map, this.point);
		Queue<String> oldData = this.pollMap();
		Queue<String> update = new LinkedList<String>();
		int i = 0;
		for(String s : oldData){
			update.add(s);
			// add in the shrouded layer
			if(i == 3)
				update.add(this.getShroudedGraphicID());
		}
		
		// store the data last seen by the avatar
		// this is what the shrouded tile will display
		shrouded.setPulledData(update);
		
		// add any newly shrouded entities to the map visitor's
		// shroudedEntity list
		List<Entity> newShrouded = map.getEntitiesOnTile(point);
		for(Entity ent : newShrouded)
			MapVisitor.addToShrouded(ent);
		map.setTileState(point, shrouded);
	}

	/**
	 * Return the name of this state.
	 */
	public String getName() {
		return "CurrentlyViewable";
	}
	
	/**
	 * Poll new data from the tile.
	 * @param map
	 * @param point
	 * @return
	 */
	private Queue<String> pollMap(){
		Queue<String> pulled = new LinkedList<String>();
		
		// pull terrain
		String terrainGraphic = map.getTerrain(point).getGraphicID();
		pulled.add(terrainGraphic);
		
		// pull decal
		String decalGraphic = map.getDecal(point);
		pulled.add(decalGraphic);
		
		// pull obstacles
		List<Obstacle> obstacleGraphics = map.getObstaclesOnTile(point);
		for(Obstacle o : obstacleGraphics)
			pulled.add(o.getGraphicID());
		
		// pull MapAoEs
		List<MapAreaOfEffect> mapAoEGraphics = map.getMapAreaOfEffect(point);
		for(MapAreaOfEffect aoe : mapAoEGraphics)
			pulled.add(aoe.getGraphicID());
		
		// pull Traps
		List<Trap> trapGraphics = map.getTraps(point);
		for(Trap t : trapGraphics)
			pulled.add(t.getGraphicID());
		
		// pull items
		List<InventoryItem> itemGraphics = map.getInventoryItemsOnTile(point);
		for(InventoryItem i : itemGraphics)
			pulled.add(i.getGraphicID());
		
		// pull Entities
		List<Entity> entGraphics = map.getEntitiesOnTile(point);
		for(Entity e : entGraphics)
			pulled.add(e.getGraphicID());
		
		// pull SkillObjects
		List<SkillObject> skillObjectGraphics = map.getSkillObjects(point);
		for(SkillObject s : skillObjectGraphics)
			pulled.add(s.getGraphicID());
		
		return pulled;
	}

	/**
	 * Return the string representation of the tile as seen by the avatar.
	 */
	public Queue<String> pullDataFromMap() {
		return pollMap();
	}
}
